package main

import (
	"encoding/json"
	"fmt"
	"os"
	"strconv"

	"github.com/xuri/excelize/v2"
)

type SmbAccount struct {
	OutUid     string                 `json:"out_uid"`
	Type       int32                  `json:"type"`
	Phone      string                 `json:"phone"`
	Email      string                 `json:"email"`
	Department string                 `json:"department"`
	OriginData map[string]interface{} `json:"originData"`
}

func excelToJson(inputPath string) error {
	f, err := excelize.OpenFile(inputPath)
	if err != nil {
		return fmt.Errorf("打开文件失败: %v", err)
	}
	defer f.Close()

	sheets := f.GetSheetList()
	if len(sheets) == 0 {
		return fmt.Errorf("Excel文件中没有工作表")
	}

	var (
		allAccounts []SmbAccount
		fileCounter = 1
	)

	for _, sheetName := range sheets {
		rows, err := f.GetRows(sheetName)
		if err != nil {
			return fmt.Errorf("读取工作表[%s]失败: %v", sheetName, err)
		}

		if len(rows) < 2 {
			fmt.Printf("工作表[%s]没有数据行，已跳过\n", sheetName)
			continue
		}

		headers := rows[0]
		headerMap := make(map[string]int)
		for i, h := range headers {
			headerMap[h] = i
		}

		requiredColumns := []string{"out_uid", "phone", "department", "email"}
		for _, col := range requiredColumns {
			if _, ok := headerMap[col]; !ok {
				return fmt.Errorf("工作表[%s]缺少必要列: %s", sheetName, col)
			}
		}

		for rowIndex, row := range rows[1:] {
			account := SmbAccount{
				OriginData: make(map[string]interface{}),
				Type:       1,
			}

			account.OutUid = safeGet(row, headerMap["out_uid"])
			account.Phone = safeGet(row, headerMap["phone"])
			account.Department = safeGet(row, headerMap["department"])
			account.Email = safeGet(row, headerMap["email"])

			for headerName, colIndex := range headerMap {
				if isFixedField(headerName) {
					continue
				}

				value := safeGet(row, colIndex)
				if numValue, err := strconv.ParseFloat(value, 64); err == nil {
					account.OriginData[headerName] = numValue
				} else if boolValue, err := strconv.ParseBool(value); err == nil {
					account.OriginData[headerName] = boolValue
				} else {
					account.OriginData[headerName] = value
				}
			}

			allAccounts = append(allAccounts, account)
			fmt.Printf("已处理工作表[%s]第%d行数据\n", sheetName, rowIndex+2)

			// 每满300条生成一个文件
			if len(allAccounts) >= 150 {
				if err := saveBatchFile(allAccounts, fileCounter); err != nil {
					return err
				}
				allAccounts = []SmbAccount{} // 重置切片
				fileCounter++
			}
		}
	}

	// 处理剩余数据
	if len(allAccounts) > 0 {
		if err := saveBatchFile(allAccounts, fileCounter); err != nil {
			return err
		}
	}

	return nil
}

// 保存批次文件
func saveBatchFile(accounts []SmbAccount, fileNumber int) error {
	filename := strconv.Itoa(fileNumber) + ".json"
	file, err := os.Create(filename)
	if err != nil {
		return fmt.Errorf("创建文件[%s]失败: %v", filename, err)
	}
	defer file.Close()

	encoder := json.NewEncoder(file)
	encoder.SetIndent("", "  ")
	if err := encoder.Encode(accounts); err != nil {
		return fmt.Errorf("JSON编码文件[%s]失败: %v", filename, err)
	}
	fmt.Printf("已生成文件: %s\n", filename)
	return nil
}

// 安全获取单元格值
func safeGet(row []string, index int) string {
	if index < len(row) {
		return row[index]
	}
	return ""
}

// 判断固定字段
func isFixedField(header string) bool {
	fixedFields := map[string]bool{
		"out_uid":    true,
		"phone":      true,
		"department": true,
		"email":      true,
		"type":       true,
	}
	return fixedFields[header]
}

func main() {
	err := excelToJson("/Users/gyl/Documents/gostudy/excel/users.xlsx")
	if err != nil {
		fmt.Println("转换失败:", err)
		return
	}
	fmt.Println("转换完成!")
}
